import sys
import argparse

def parse_patch_file(file_path):
    """纯文本解析 patch 文件，返回元信息和修改块列表"""
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            lines = f.readlines()
    except FileNotFoundError:
        print(f"❌ 文件不存在: {file_path}", file=sys.stderr)
        return None, None
    
    metadata = []  # 全局元信息（From, Date, Subject等）
    files = []     # 所有文件及其修改块
    current_file = None
    current_hunk = None
    in_hunk = False

    for line in lines:
        if line.startswith("diff --git"):
            # 新文件开始
            if current_file is not None:
                if current_hunk is not None:
                    current_file['hunks'].append(current_hunk)
                files.append(current_file)
            current_file = {'header': line, 'hunks': []}
            current_hunk = None
            in_hunk = False
        elif line.startswith("@@ ") and "@@ " in line:
            # 新修改块开始
            if current_file is not None and current_hunk is not None:
                current_file['hunks'].append(current_hunk)
            current_hunk = {'header': line, 'lines': [line]}
            in_hunk = True
        elif current_hunk is not None and in_hunk:
            # 修改块内容行
            current_hunk['lines'].append(line)
        elif current_file is not None:
            # 文件级头部信息（如index, ---, +++）
            if not line.startswith("---") and not line.startswith("+++"):
                current_file['header'] += line
        else:
            # 全局元信息
            metadata.append(line)
    
    # 添加最后一个文件
    if current_file is not None:
        if current_hunk is not None:
            current_file['hunks'].append(current_hunk)
        files.append(current_file)
    
    return ''.join(metadata), files

def display_hunk(hunk, file_idx, hunk_idx):
    """显示单个修改块"""
    print("\n" + "="*60)
    print(f"📄 文件 {file_idx+1}")
    print(f"🔍 修改块 {hunk_idx+1}")
    print("-"*60)
    print(''.join(hunk['lines']).strip())
    print("="*60 + "\n")

def select_hunks(files):
    """交互式选择要保留的修改块"""
    selected = []
    for file_idx, file_data in enumerate(files):
        for hunk_idx, hunk in enumerate(file_data['hunks']):
            display_hunk(hunk, file_idx, hunk_idx)
            choice = input("保留此修改块？[Y/n] ").strip().lower() or 'y'
            if choice in ['y', 'yes']:
                selected.append((file_data['header'], hunk))
                print("✅ 已保留\n")
            else:
                print("❌ 已丢弃\n")
    return selected

def generate_new_patch(metadata, selected, output_path):
    """生成新 patch 文件"""
    try:
        with open(output_path, 'w', encoding='utf-8') as f:
            # 写入全局元信息
            f.write(metadata.strip() + "\n\n")
            # 写入选中的修改块
            for file_header, hunk in selected:
                f.write(file_header)  # 文件头
                f.write(''.join(hunk['lines']))  # 修改块内容
                f.write("\n")  # 块间分隔
        print(f"🎉 成功生成新 patch: {output_path}")
        return True
    except Exception as e:
        print(f"❌ 写入失败: {str(e)}", file=sys.stderr)
        return False

def main():
    parser = argparse.ArgumentParser(description='Git Patch 编辑工具（纯原生版）')
    parser.add_argument('-i', '--input', required=True, help='输入 patch 文件路径')
    parser.add_argument('-o', '--output', required=True, help='输出新 patch 文件路径')
    args = parser.parse_args()

    # 1. 解析 patch（纯文本，无依赖）
    print(f"📄 正在解析: {args.input}")
    metadata, files = parse_patch_file(args.input)
    if not files:
        print("❌ 未找到任何修改块，请检查文件格式", file=sys.stderr)
        sys.exit(1)

    # 2. 选择修改块
    total_hunks = sum(len(f['hunks']) for f in files)
    print(f"共 {len(files)} 个文件，{total_hunks} 个修改块")
    selected = select_hunks(files)
    if not selected:
        print("⚠️ 未选择任何修改块，不会生成输出文件", file=sys.stderr)
        sys.exit(1)

    # 3. 生成新文件
    if not generate_new_patch(metadata, selected, args.output):
        sys.exit(1)

if __name__ == "__main__":
    main()